/********************************************************************
	created:	2010/08/26
	created:	26:8:2010   17:47
	filename: 	qyQuatT.h
	author:		Xiong Jiayu
	purpose:	
*********************************************************************/
#pragma once

#ifndef __QYQUATT_H__
#define __QYQUATT_H__

#include "qyQuat.h"
#include "qyVector3.h"

/*
===========================================
struct QuatT
===========================================
*/
struct QuatT
{
public:
	Quat	q;
	Vector3	t;

public:
						QuatT();
						QuatT( const Quat &q, const Vector3 &t );
						QuatT( const QuatT &qt );

	void				Set( const Quat &q, const Vector3 &t );
	void				Set( const Quat &q );
	void				Set( const Vector3 &t );

	QuatT				Inverse( void ) const;
	QuatT &				InverseSelf( void );
	void				Identity( void );

	QuatT & 			Slerp( const QuatT &from, const QuatT &to, float t );
	QuatT &				SlerpFast( const QuatT &from, const QuatT &to, float t );

	void				ToMatrix4( Matrix4 &mat ) const;
	void				FromMatrix4( const Matrix4 &mat );

	QuatT				operator*( const QuatT &a ) const;
	void				operator*=( const QuatT &a );
	QuatT &				operator=( const QuatT &a );
};

//-----------------------------------------------------------------------
QY_INLINE QuatT::QuatT()
{
}

//-----------------------------------------------------------------------
QY_INLINE QuatT::QuatT( const Quat &_q, const Vector3 &_t )
: q( _q )
, t( _t )
{
}

//-----------------------------------------------------------------------
QY_INLINE QuatT::QuatT( const QuatT &qt )
: q( qt.q )
, t( qt.t )
{
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::Set( const Quat &_q, const Vector3 &_t )
{
	q = _q;
	t = _t;
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::Set( const Quat &_q )
{
	q = _q;
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::Set( const Vector3 &_t )
{
	t = _t;
}

//-----------------------------------------------------------------------
QY_INLINE QuatT QuatT::Inverse( void ) const
{
	Quat invQ = q.Inverse();
	return QuatT( invQ, invQ*(-t) );
}

//-----------------------------------------------------------------------
QY_INLINE QuatT & QuatT::InverseSelf( void )
{
	q.InverseSelf();
	t=q*(-t);
	return (*this);
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::Identity( void )
{
	q.Identity();
	t.Zero();
}

//-----------------------------------------------------------------------
QY_INLINE QuatT & QuatT::Slerp( const QuatT &from, const QuatT &to, float weight )
{
	q.Slerp( from.q, to.q, weight );
	t = from.t * ( 1 - weight ) + to.t * weight;
	return (*this);
}

//-----------------------------------------------------------------------
QY_INLINE QuatT & QuatT::SlerpFast( const QuatT &from, const QuatT &to, float weight )
{
	q.SlerpFast( from.q, to.q, weight );
	t = from.t * ( 1 - weight ) + to.t * weight;
	return (*this);
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::FromMatrix4( const Matrix4 &mat )
{
	q.FromMatrix4( mat );
	mat.ToVec3( t );
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::ToMatrix4( Matrix4 &mat ) const
{
	q.ToMatrix4( mat );
	mat.FromVec3( t );
}

//-----------------------------------------------------------------------
QY_INLINE QuatT	QuatT::operator*( const QuatT &a ) const
{
	return QuatT( a.q * q, a.q * t + a.t );
}

//-----------------------------------------------------------------------
QY_INLINE void QuatT::operator *=( const QuatT &a )
{
	QuatT r = (*this) * a;
	q = r.q;
	t = r.t;
}

//-----------------------------------------------------------------------
QY_INLINE QuatT &QuatT::operator =( const QuatT &a )
{
	q = a.q;
	t = a.t;
	return (*this);
}

#endif
 